package com.iceland.common.message;

import com.iceland.common.kryo.KryoUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MarkerFactory;

@Slf4j
public class CmdMessageDecoder extends LengthFieldBasedFrameDecoder {

//    private static int maxFrameLength=1024*1024*5;
//    private static int lengthFieldOffset=0;
//    private static int lengthFieldLength=4;

    private static final int MAX_FRAME_LENGTH = 1024*1024*20;
    private static final int LENGTH_FIELD_OFFSET = 0;
    private static final int LENGTH_FIELD_LENGTH = 4;

    private static final int LENGTH_ADJUSTMENT = 0;
    private static final int INITIAL_BYTES_TO_STRIP = 4;

    public CmdMessageDecoder() {
        super(MAX_FRAME_LENGTH, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH,LENGTH_ADJUSTMENT,INITIAL_BYTES_TO_STRIP);
    }

    public CmdMessageDecoder( int maxFrameLength,
                              int lengthFieldOffset, int lengthFieldLength,
                              int lengthAdjustment, int initialBytesToStrip) {
        super(  maxFrameLength,
         lengthFieldOffset,  lengthFieldLength,
         lengthAdjustment,  initialBytesToStrip);
    }

    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        //获得一段可以构成Message的完整的数据
        in= (ByteBuf)super.decode(ctx, in);
        if(in==null){
            return null;
        }
        long sum=8;
        //构造Message
        int type=in.readInt();
        //获取请求头长度
        int headerLength=in.readInt();
        sum+=headerLength;
        //序列化请求头
        Header header =null;
        if(headerLength>0){
            byte[] headerBytes=new byte[headerLength];
            in.readBytes(headerBytes);
            header = KryoUtil.readFromByteArray(headerBytes);
        }
        int readableBytes=in.readableBytes();
        //剩下的都是data
        if(in.readableBytes()>0){
            sum+=in.readableBytes()+1;
            int datatype=in.readByte();

            if(datatype==DataType.BYTEBUF.getType()){
                log.debug(MarkerFactory.getMarker(this.getClass().getTypeName()),"接收到消息,消息类型:{},消息转化比，data:message={}/{}={}",type,readableBytes,sum,readableBytes*1.0/sum);
                return new CmdMessage(type,header,in);

            }
            else {
                byte[] dataBytes=new byte[in.readableBytes()];
                in.readBytes(dataBytes);
                Object o = KryoUtil.readFromByteArray(dataBytes);
                in.release();
                log.debug(MarkerFactory.getMarker(this.getClass().getTypeName()),"接收到消息,消息类型:{},消息转化比，data:message={}/{}={}",type,readableBytes,sum,readableBytes*1.0/sum);
                return new CmdMessage(type,header,o);
            }

        }
        in.release();
        log.debug(MarkerFactory.getMarker(this.getClass().getTypeName()),"消息解码完成,消息类型:{},消息转化比，data:message={}/{}={}",type,readableBytes,sum,readableBytes*1.0/sum);
        return new CmdMessage(type,header,null);
    }


}
